#include "unitReader.h"

int UnitReader::load(DescriptorManager *dm, char* data_path) {
  int ret;

  m_dm = dm;

  strcpy(m_data_path, data_path);
  
  ret = load_mmap();
  if(ret != S_RET) {
    FATAL("error load mmap");
    return E_RET;
  }

  ret = load_idx();
  if(ret != S_RET) {
    FATAL("error load unit idx");
    return E_RET;
  }

  return S_RET;
}


int UnitReader::load_idx() {
  int ret;
  char fname[NAME_LEN];
  IdxItem* pidx;

  sprintf(fname, "%s/%s", 
      m_data_path, 
      UNIT_IDX_NAME);
  FILE* fp = fopen(fname, "r");
  if(fp == NULL) {
    FATAL("error fopen[%s]", fname);
    return E_RET;
  }

  ret = fread(&m_rsc_num, sizeof(uint32_t), 1, fp);
  assert(ret == 1);

  ret = fread(&m_link_num, sizeof(uint32_t), 1, fp);
  assert(ret == 1);

  items = (IdxItem*)malloc(sizeof(IdxItem) * m_link_num);
  assert(items);

  for(uint32_t i = 0 ; i < m_link_num ; ++i) {
    pidx = &items[i];

    pidx->fno = (uint32_t*)malloc(m_rsc_num * sizeof(uint32_t));
    assert(pidx->fno);

    pidx->off = (uint32_t*)malloc(m_rsc_num * sizeof(uint32_t));
    assert(pidx->fno);

    pidx->len = (uint32_t*)malloc(m_rsc_num * sizeof(uint32_t));
    assert(pidx->fno);

    //jump beyond the id 
    fseek(fp, sizeof(uint32_t), SEEK_CUR);

    for(uint32_t j = 0 ; j < m_rsc_num ; ++j) {
      ret = fread(&pidx->fno[j], sizeof(uint32_t), 1, fp);
      assert(ret == 1);

      ret = fread(&pidx->off[j], sizeof(uint32_t), 1, fp);
      assert(ret == 1);

      ret = fread(&pidx->len[j], sizeof(uint32_t), 1, fp);
      assert(ret == 1);

    }
  }

  return S_RET;
}

int UnitReader::load_mmap() {
  char fname[NAME_LEN];
  m_unit_fnum = 0;
  int fds[MAX_UNIT_FNUM];
  int fsize[MAX_UNIT_FNUM];

  //open 1st
  sprintf(fname, "%s/%s.%d", m_data_path, 
      UNIT_NAME,
      0);
  FILE* tfp = fopen(fname, "r");
  if(tfp == NULL) {
    FATAL("error fopen [%s], merge fatal", fname);
    return E_RET;
  }
  fclose(tfp);

  while(1) {
    if(m_unit_fnum >= MAX_UNIT_FNUM) {
      FATAL("error : unit fnum: file [%d] exeeds max[%d]",
	  m_unit_fnum, MAX_UNIT_FNUM);
      return E_RET;
    }

    sprintf(fname, "%s/%s.%d", m_data_path, 
	UNIT_NAME,
	m_unit_fnum);

    fds[m_unit_fnum] = open(fname, O_RDONLY, 0666);
    if(fds[m_unit_fnum] < 0) {
      NOTICE("finish on file[%s]", fname);
      break;
    }

    fsize[m_unit_fnum] = lseek(fds[m_unit_fnum], 0, SEEK_END) ;
    if (fsize[m_unit_fnum] <= 0)
    {
      FATAL("lseek error:%s", fname);
      return E_RET;
    }


    m_mapptr[m_unit_fnum] = 
      (char*)mmap(NULL, fsize[m_unit_fnum], PROT_READ, MAP_SHARED, fds[m_unit_fnum], 0);
    assert(m_mapptr[m_unit_fnum] != MAP_FAILED);

    NOTICE("mmap [%s] ok", fname);

    m_unit_fnum++;
  }

  return S_RET;
}
